#include <linux/acpi.h>
#include <linux/ioport.h>
#include <linux/cache.h>
#include <linux/init.h>
#include <linux/of_fdt.h>
#include <linux/mm.h>

#include <asm/fixmap.h>
#include <asm/memblock.h>
#include <asm/mmu_context.h>

phys_addr_t __fdt_pointer __initdata;

static void __init setup_machine_fdt(phys_addr_t dt_phys)
{
	void *dt_virt = fixmap_remap_fdt(dt_phys);
	const char *name;

	if (!dt_virt || !early_init_dt_scan(dt_virt)) {
		pr_crit("\n"
			"Error: invalid device tree blob at physical address %pa (virtual address 0x%p)\n"
			"The dtb must be 8-byte aligned and must not exceed 2 MB in size\n"
			"\nPlease check your bootloader.",
			&dt_phys, dt_virt);

		while (true)
			cpu_relax();
	}

	name = of_flat_dt_get_machine_name();
	if (!name)
		return;

	pr_info("Machine model: %s\n", name);
	dump_stack_set_arch_desc("%s (DT)", name);
}

/*
 * The recorded values of x0 .. x3 upon kernel entry.
 */
u64 __cacheline_aligned boot_args[4];

void __init setup_arch(char **cmdline_p)
{
	early_fixmap_init();

	setup_machine_fdt(__fdt_pointer);

	/*
	 * TTBR0 is only used for the identity mapping at this stage. Make it
	 * point to zero page to avoid speculatively fetching new entries.
	 */
	cpu_uninstall_idmap();

	arm64_memblock_init();

	paging_init();

	if (acpi_disabled)
		unflatten_device_tree();
}
